package net.wicp.tams.duckula.ops.services;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Properties;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.collections.CollectionUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.zookeeper.data.Stat;

import com.alibaba.fastjson.JSONObject;

import ch.qos.logback.classic.Logger;
import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.commons.Conf;
import net.wicp.tams.commons.Result;
import net.wicp.tams.commons.apiext.IOUtil;
import net.wicp.tams.commons.apiext.StringUtil;
import net.wicp.tams.commons.constant.dic.YesOrNo;
import net.wicp.tams.duckula.common.ZkClient;
import net.wicp.tams.duckula.common.ZkUtil;
import net.wicp.tams.duckula.common.beans.Pos;
import net.wicp.tams.duckula.common.beans.Task;
import net.wicp.tams.duckula.common.constant.ZkPath;
import net.wicp.tams.duckula.ops.beans.Server;
import net.wicp.tams.duckula.ops.servicesBusi.DuckulaAssitImpl;
import net.wicp.tams.duckula.ops.servicesBusi.DuckulaUtils;
import net.wicp.tams.duckula.ops.servicesBusi.IDuckulaAssit;

@Slf4j
public class InitDuckula implements ServletContextListener {

	public static PathChildrenCacheListener taskListener = new PathChildrenCacheListener() {

		private IDuckulaAssit duckulaAssit = new DuckulaAssitImpl();// TODO

		@Override
		public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
			ChildData data = event.getData();
			switch (event.getType()) {
			case CHILD_ADDED:// 新增不关注
				System.out.println("TASK_ADD : " + data.getPath() + "  数据:" + data.getData());
				break;
			case CHILD_REMOVED:
				ChangeTask(data);
				break;
			case CHILD_UPDATED:// 修改不关注
				System.out.println("TASK_UPDATE : " + data.getPath() + "  数据:" + data.getData());
				break;
			default:
				break;
			}
		}

		private void ChangeTask(ChildData data) throws UnsupportedEncodingException {
			String[] paths = data.getPath().split("/");
			String taskId = paths[paths.length - 2];
			log.info("taskId:[{}]被下线.", taskId);

			Task task = ZkUtil.buidlTask(taskId);
			if (task != null && task.getRun() == YesOrNo.yes) {// 需要启动
				List<String> locks = ZkUtil.lockIps(taskId);
				if (CollectionUtils.isEmpty(locks)) {// 没有启动
					String removeIp = new String(data.getData());// 要剔除的ＩＰ
					Server server = duckulaAssit.selServer(removeIp);
					Result result = duckulaAssit.startTask(taskId, server, true);
					log.info("taskId:[{}],task试着重启结果{}.", taskId,result.getMessage());
				}
			}
		}
	};

	@Override
	public void contextInitialized(ServletContextEvent paramServletContextEvent) {
		String duckulaHome = System.getenv("DUCKULA_HOME");
		log.info("use  env:{}", duckulaHome);
		Properties prop = null;
		if (StringUtil.isNotNull(duckulaHome)) {
			prop = IOUtil.fileToProperties(new File(String.format("%s/conf/duckula-ops.properties", duckulaHome)));
			if (prop.isEmpty()) {
				log.error("没有取得属性文件,请确认设置了DUCKULA_HOME环境变量");
				throw new RuntimeException("没有取得属性文件,请确认设置了DUCKULA_HOME环境变量");
			}
			Conf.overProp(prop);
		}

		// 初始化目录
		Stat stat = ZkClient.getInst().exists("/duckula");
		if (stat == null) {
			ZkClient.getInst().createNode("/duckula", "the duckula root");
		}
		for (ZkPath zkPath : ZkPath.values()) {
			Stat statTemp = ZkUtil.exists(zkPath);
			if (statTemp == null) {
				ZkClient.getInst().createNode(zkPath.getRoot(), null);
			}
		}

		// 监听pos
		PathChildrenCacheListener childrenCacheListener = new PathChildrenCacheListener() {
			@Override
			public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
				ChildData data = event.getData();
				switch (event.getType()) {
				case CHILD_ADDED:
					System.out.println("CHILD_ADD : " + data.getPath() + "  数据:" + data.getData());
					break;
				case CHILD_REMOVED:
					System.out.println("CHILD_REMOVED : " + data.getPath() + "  数据:" + data.getData());
					break;
				case CHILD_UPDATED:
					alterDate(data.getData());
					break;
				default:
					break;
				}
			}

			private void alterDate(byte[] data) throws UnsupportedEncodingException {
				String posvalue = new String(data, "UTF-8");
				Pos pos = JSONObject.parseObject(posvalue, Pos.class);
				long masterServerId = pos.getMasterServerId();
				Logger logger = DuckulaUtils.getPosLog(masterServerId);
				logger.info(posvalue);
			}
		};
		ZkClient.getInst().createPathChildrenCache(ZkPath.pos.getRoot(), childrenCacheListener);

		List<String> allTaskIds = ZkUtil.findSubNodes(ZkPath.tasks);
		for (String taskId : allTaskIds) {
			ZkClient.getInst().createPathChildrenCache(ZkPath.tasks.getPath(taskId), taskListener);
		}
	}

	@Override
	public void contextDestroyed(ServletContextEvent paramServletContextEvent) {
		System.out.println("bb");
	}

}
